package at.jku.cp.mir;

import java.util.Map;
import java.util.Set;

public class ArtistVectorCosineSimilarity implements ArtistVectorSimilarity
{

	public double getSimilarity(ArtistVector aV1, ArtistVector aV2)
	{
		double dotProduct = dotProduct(aV1, aV2);
		double aV1Magn = magnitude(aV1);
		double aV2Magn = magnitude(aV2);

		return dotProduct / (aV1Magn * aV2Magn);
	}

	protected double dotProduct(ArtistVector aV1, ArtistVector aV2)
	{
		Map<String, Double> aV1Map = aV1.getTagTfIdfMap();
		Map<String, Double> aV2Map = aV2.getTagTfIdfMap();

		double dotProduct = 0.0;

		Set<String> tags = aV1Map.keySet();
		for (String tag : tags)
		{
			Double av1Value = aV1Map.get(tag);
			Double av2Value = aV2Map.get(tag);

			if (av1Value != null && av2Value != null)
				dotProduct += av1Value.doubleValue() * av2Value.doubleValue();
		}

		return dotProduct;
	}

	protected double magnitude(ArtistVector av)
	{
		Map<String, Double> avMap = av.getTagTfIdfMap();
		Set<String> tags = avMap.keySet();
		double sum = 0.0;
		for (String tag : tags)
		{
			Double value = avMap.get(tag);
			sum += Math.pow(value.doubleValue(), 2.0);
		}
		return Math.sqrt(sum);
	}
}
